/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package bgu.ppm.gtm.congestion;

import bgu.ppm.gtm.base.GameTheoryModel;
import bgu.ppm.gtm.base.ImmutableStrategy;
import bgu.ppm.gtm.base.PlayerValueFunction;
import bgu.ppm.gtm.base.Strategies;
import bgu.ppm.gtm.base.StrategyProfile;
import bgu.ppm.gtm.base.StrategyProfileBuilder;
import java.util.Collection;

/**
 *
 * @author User
 */
public class CongestionGameModel extends GameTheoryModel {

    private int numResources;
    private ResourcesCostFunction resourcesCostFunction;
    private StrategyProfileBuilder strategyProfileBuilder;
    private Strategies[] strategies;

    @Override
    protected void _initialize() {
        this.strategyProfileBuilder = new StrategyProfileBuilder() {
            @Override
            public StrategyProfile build(ImmutableStrategy... strategies) {
                return new CongestionStrategyProfile(numResources, strategies);
            }

            @Override
            public StrategyProfile build(Collection<ImmutableStrategy> strategies) {
                return new CongestionStrategyProfile(numResources, strategies);
            }

            @Override
            public StrategyProfile build(StrategyProfile profile, ImmutableStrategy... strategies) {
                return new CongestionStrategyProfile((CongestionStrategyProfile) profile, strategies);
            }
        };
        setCostFunction(new PlayerValueFunction() {
            @Override
            public double calculate(int player, ImmutableStrategy strategy, StrategyProfile profile) {
                CongestionStrategyProfile cprofile = (CongestionStrategyProfile) profile;
                double cost = 0;
                for (int i = 0; i < numResources; i++) {
                    cost += strategy.get(i) * getResourcesCostFunction().cost(i, cprofile.getCongestionForResourceWithoutPlayer(i, player) + strategy.get(i));
                }

                return cost;
            }
        });

        setUtilityFunction(new PlayerValueFunction() {
            @Override
            public double calculate(int player, ImmutableStrategy strategy, StrategyProfile profile) {
                return -1 * getCostFunction().calculate(player, strategy, profile);
            }
        });

    }

    public int getNumberOfResources() {
        return numResources;
    }

    public ResourcesCostFunction getResourcesCostFunction() {
        return resourcesCostFunction;
    }

    public void setResourcesCostFunction(ResourcesCostFunction resourcesCostFunction) {
        this.resourcesCostFunction = resourcesCostFunction;
    }

    public void setNumberOfResources(int numResources) {
        this.numResources = numResources;
    }

    @Override
    public void setNumberOfAgents(int agents) {
        super.setNumberOfAgents(agents); //To change body of generated methods, choose Tools | Templates.
    }

    @Override
    public Strategies getStrategiesFor(int player) {
        return strategies[player];
    }

    @Override
    protected StrategyProfileBuilder getStrategyProfileBuilder() {
        return strategyProfileBuilder;
    }

    public void setStrategies(Strategies[] strategies) {
        this.strategies = strategies;
    }
}
